其他
Caffeine如何变热?
本文字数:4066字
预计阅读时间:10分钟
一、何谓热点数据?
永久性热点数据 比如某部热门电视剧,在其播出期间,观看频次非常高,那么在此期间,该电视剧可以算作永久性热点数据。 阶段性热点数据 周期性热点 例如最近的欧洲杯,比赛视频观看频次都会随着比赛场次呈现出周期性的波动。 突发性热点 主要来源于突发事件:例如地震报道,明星直播等等。
二、权衡
永久性热点:其访问频率随时间变化波动基本不大,这种数据尽量全部缓存起来。 突发性热点:其访问频率由于突发性而无法预估,故只能制定有效的检测手段。 周期性热点:虽然其访问频率随时间呈现周期性的波动,但是在每个周期内,都可以看做突发性热点。
内存越大,缓存的数据就越多,理论上命中率就会越高。 内存越小,缓存的数据就越少,理论上命中率就会越低。
三、最佳命中率之Caffeine
在大多数的实际场景中,访问频率会随着时间发生变化,而LFU无法自适应。 维护大量统计数据,内存消耗极大。
如果存在大量只访问一次的数据(长尾流量),那么TinyLFU中的计数器将被无效占用,从而影响频率判断。 TinyLFU如何反映时间变化影响的频率变化? 突发的数据可能还没有累计够足够的频率就被淘汰了,导致命中率下降。
四、热点探测
在本地内存中做统计,而对于互联网应用来说,通常会部署多个实例,流量均分到每个实例上, 这样,单个实例的数据情况无法代表整个应用的情况。所以从应用的整体角度看,可能某个数据是热的,但是在单个实例上并不明显。 当发现某个数据变热时,Caffeine只能在本地内存中生效,无法通知到其他实例。
在客户端埋点,采用环形计数器统计数据的访问量,并定时上报统计数据。 探测器用于汇总客户端的统计数据,采用滑动窗口来做集中式探测,发现高频数据及时通知客户端缓存起来。
① 客户端key计数统计。 ② 客户端统计轮切换。 ③ 客户端推送统计数据到探测器的缓冲队列。 ④ 探测器并行消费统计数据。 ⑤ 探测器采用滑动窗口统计key的访问频率。 ⑥ 探测器通知客户端Caffeine缓存热点数据。
永久性热点 该类数据的特点就是访问频率较为稳定,可以针对此类数据设置固定的频率阈值。 当此类数据在客户端快过期时,立马统计并上报访问情况,就可以保证该类数据一直缓存在客户端中。 突发性热点 该类数据特点就是突发性的高频访问,随着时间进行衰减,探测系统采用滑动窗口计数, 既能够保证达到阈值时及时探测到,又不会因为时间衰减而处于阈值边缘漏掉的情况。 周期性热点 周期性热点在每个周期内都可以看做是突发性热点,故不再赘述。
五、热咖啡
etcd:配置中心,用于服务发现和配置等。 client:客户端SDK,用于数据收集上报和接收热key。 worker:用于接收客户端数据上报和热key计算。 dashboard:管理后台和数据展示。
针对客户端,需要单独的用户名和密码,但是他们共同拥有同样的角色,就是client,而client对资源/hotcaffeine/只有只读权限 针对worker,由于是内部应用,单独建立一个worker的角色,对资源/hotcaffeine/具有读写权限。 针对dashboard,由于是内部应用,需要给各个用户赋权,故其拥有root用户和权限。
多缓存配置: HotCaffeine客户端支持配置多个Caffeine缓存,并且支持动态调整缓存大小和过期时间。 灵活的热点规则配置: 所谓热点规则就是针对热点数据的滑窗统计数据进行配置,例如在3秒内达到5次访问即认为变为热点数据。 不同的热点规则支持对应到不同的缓存中,即热点规则和缓存缓存是多对多的。 而且支持前缀规则匹配和动态修改,业务端可以实时修改规则实时生效。 热点数据实时查看: 点击热key名可以查看热key在各个客户的实例对应的值: 调用量分布: 业务端很少知道自己缓存的数据分布情况,使用调用量分布功能业务端就能大概知道key的分布情况,用于设置缓存大小和过期时间等有很大帮助。 下面举个具体的例子来说明一下,假设业务系统在某段时间内共有如下6个key访问,访问总量为100: 那么,如果这段时间内,key6在缓存中的话,命中率就能达到50%。而key1和key2在缓存中的话,命中率仅为10%。 根据这个简单的例子,来看下调用量分布:
调用量=2的key有944个,那么调用量为2的key的总调用量为1888,它占本次统计的总调用量的比例为17.95%。 也就是说如果把调用量>=2的key都缓存下来,命中率为(1-43.86%)=56.14%。 左边第一列是调用量,也就是上面那个例子中说的访问量。 第二列是key的数量,根据这列可以大概知道key的多少(非重复),进而可以设置缓存大小。 第三列是调用量占比,比如 以第二行的数据为例来说明一下: 第四列是key的生存时间数据,可以参照个这个数据设置缓存的过期时间。
将数据缓冲队列拆分为多个小队列,数据均匀hash到不同的队列,保障同样hash的数据肯定只在一个队列中,将并发变为并行处理。 针对某个待检测数据来说,后续的滑窗计数等不存在并发问题,故消除全部锁竞争代码。
六、参考文献
Caffeine 万字详解本地缓存之王-Caffeine W-TinyLFU论文 Segment LUR 对象存储系统中热点数据的研究 hotkey
2021-01-14
2021-08-26
2021-08-19
2021-07-15
2021-07-08